/*
 * Copyright 2024, Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */

#ifndef _LOONGARCH_VESA_PRIVATE_H
#define _LOONGARCH_VESA_PRIVATE_H

#include <Accelerant.h>
#include <Drivers.h>
#include <PCI.h>
#include <OS.h>

// 最大支持的设备数量
#define MAX_LOONGARCH_VESA_DEVICES 4

// 设备名称格式
#define DEVICE_FORMAT "loongarch_vesa_%04x_%04x_%02x%02x%02x"

// 驱动程序前缀
#define DRIVER_PREFIX "loongarch_vesa"

// 调试宏
#ifdef DEBUG
#define TRACE(x...) dprintf(DRIVER_PREFIX ": " x)
#else
#define TRACE(x...)
#endif

// 错误输出宏
#define ERROR(x...) dprintf(DRIVER_PREFIX ": " x)

// 寄存器访问宏
#define WREG32(reg, val) (*(vuint32 *)((vuint8 *)di->regs + (reg)) = (val))
#define RREG32(reg) (*(vuint32 *)((vuint8 *)di->regs + (reg)))

// LS7A2000显示控制器寄存器定义
#define LS7A_DC_REG_BASE 0x00000000
#define LS7A_DC_REVISION (LS7A_DC_REG_BASE + 0x0000)    // 版本寄存器
#define LS7A_DC_CONFIG (LS7A_DC_REG_BASE + 0x0004)      // 配置寄存器
#define LS7A_DC_FB_ADDR (LS7A_DC_REG_BASE + 0x0008)     // 帧缓冲地址寄存器
#define LS7A_DC_FB_STRIDE (LS7A_DC_REG_BASE + 0x000C)   // 帧缓冲行跨度寄存器
#define LS7A_DC_FB_ORIGIN (LS7A_DC_REG_BASE + 0x0010)   // 帧缓冲原点寄存器
#define LS7A_DC_HDISPLAY (LS7A_DC_REG_BASE + 0x0014)    // 水平显示寄存器
#define LS7A_DC_HSYNC (LS7A_DC_REG_BASE + 0x0018)       // 水平同步寄存器
#define LS7A_DC_VDISPLAY (LS7A_DC_REG_BASE + 0x001C)    // 垂直显示寄存器
#define LS7A_DC_VSYNC (LS7A_DC_REG_BASE + 0x0020)       // 垂直同步寄存器
#define LS7A_DC_CURSOR_POS (LS7A_DC_REG_BASE + 0x0024)  // 光标位置寄存器
#define LS7A_DC_CURSOR_ADDR (LS7A_DC_REG_BASE + 0x0028) // 光标地址寄存器
#define LS7A_DC_CURSOR_BG (LS7A_DC_REG_BASE + 0x002C)   // 光标背景色寄存器
#define LS7A_DC_CURSOR_FG (LS7A_DC_REG_BASE + 0x0030)   // 光标前景色寄存器
#define LS7A_DC_RESET (LS7A_DC_REG_BASE + 0x0034)       // 复位寄存器
#define LS7A_DC_EDID_START (LS7A_DC_REG_BASE + 0x1000)  // EDID数据起始寄存器

// 配置寄存器位定义
#define LS7A_DC_CONFIG_ENABLE 0x00000001       // 显示控制器使能
#define LS7A_DC_CONFIG_CURSOR 0x00000002       // 光标使能
#define LS7A_DC_CONFIG_HSYNC_POL 0x00000004    // 水平同步极性
#define LS7A_DC_CONFIG_VSYNC_POL 0x00000008    // 垂直同步极性
#define LS7A_DC_CONFIG_FORMAT_MASK 0x00000070  // 颜色格式掩码
#define LS7A_DC_CONFIG_FORMAT_8BPP 0x00000010  // 8位每像素
#define LS7A_DC_CONFIG_FORMAT_16BPP 0x00000020 // 16位每像素
#define LS7A_DC_CONFIG_FORMAT_24BPP 0x00000030 // 24位每像素
#define LS7A_DC_CONFIG_FORMAT_32BPP 0x00000040 // 32位每像素

// 显示模式标志
#define DISPLAY_MODE_MASK 0x00000007
#define DISPLAY_MODE_640_480_60HZ 0
#define DISPLAY_MODE_800_600_60HZ 1
#define DISPLAY_MODE_1024_768_60HZ 2
#define DISPLAY_MODE_1280_1024_60HZ 3
#define DISPLAY_MODE_1440_900_60HZ 4
#define DISPLAY_MODE_1680_1050_60HZ 5
#define DISPLAY_MODE_1920_1080_60HZ 6
#define DISPLAY_MODE_1920_1200_60HZ 7

// 颜色空间标志
#define COLOR_SPACE_MASK 0x00000070
#define COLOR_SPACE_RGB15 0x00000010
#define COLOR_SPACE_RGB16 0x00000020
#define COLOR_SPACE_RGB24 0x00000030
#define COLOR_SPACE_RGB32 0x00000040

// 魔数定义
#define LOONGARCH_VESA_PRIVATE_DATA_MAGIC 'LAVS'

// 光标位置结构
typedef struct
{
    uint16 x; // X坐标
    uint16 y; // Y坐标
} loongarch_vesa_cursor_position;

// 光标形状结构
typedef struct
{
    uint16 width;  // 宽度
    uint16 height; // 高度
    uint16 hot_x;  // 热点X坐标
    uint16 hot_y;  // 热点Y坐标
    uint8 *data;   // 光标数据
} loongarch_vesa_cursor_shape;

// IOCTL命令
enum
{
    LOONGARCH_VESA_GET_DEVICE_INFO = B_DEVICE_OP_CODES_END + 1,
    LOONGARCH_VESA_GET_EDID,
    LOONGARCH_VESA_SET_DISPLAY_MODE,
    LOONGARCH_VESA_GET_DISPLAY_MODE,
    LOONGARCH_VESA_GET_FRAME_BUFFER_CONFIG,
    LOONGARCH_VESA_SET_DPMS_MODE,
    LOONGARCH_VESA_GET_DPMS_MODE,
    LOONGARCH_VESA_SET_BRIGHTNESS,
    LOONGARCH_VESA_GET_BRIGHTNESS,
    LOONGARCH_VESA_SET_CURSOR_SHAPE,
    LOONGARCH_VESA_SET_CURSOR_POSITION,
    LOONGARCH_VESA_SHOW_CURSOR,
    LOONGARCH_VESA_HIDE_CURSOR
};

// 共享信息结构
typedef struct
{
    area_id area;                      // 共享区域ID
    uint32 magic;                      // 魔数，用于验证
    phys_addr_t physical_frame_buffer; // 帧缓冲物理地址
    uint8 *frame_buffer;               // 帧缓冲虚拟地址
    uint32 frame_buffer_size;          // 帧缓冲大小

    area_id regs_area;         // 寄存器区域ID
    uint8 *regs;               // 寄存器虚拟地址
    phys_addr_t physical_regs; // 寄存器物理地址
    uint32 regs_size;          // 寄存器区域大小

    area_id cursor_area;                // 光标区域ID
    uint8 *cursor_buffer;               // 光标缓冲区虚拟地址
    phys_addr_t physical_cursor_buffer; // 光标缓冲区物理地址
    uint32 cursor_buffer_size;          // 光标缓冲区大小

    uint32 width;            // 显示宽度
    uint32 height;           // 显示高度
    uint32 bytes_per_row;    // 每行字节数
    uint32 bits_per_pixel;   // 每像素位数
    color_space color_space; // 颜色空间
    uint32 current_mode;     // 当前显示模式

    uint32 dpms_mode;  // DPMS模式
    uint32 brightness; // 亮度

    uint32 revision;      // 硬件版本
    bool hardware_cursor; // 是否支持硬件光标

    color_space cursor_format; // 光标格式
    uint32 cursor_width;       // 光标宽度
    uint32 cursor_height;      // 光标高度
    uint32 cursor_hot_x;       // 光标热点X坐标
    uint32 cursor_hot_y;       // 光标热点Y坐标
    bool cursor_visible;       // 光标是否可见
    uint32 cursor_x;           // 光标X坐标
    uint32 cursor_y;           // 光标Y坐标

    bool has_edid;   // 是否有EDID数据
    uint8 edid[128]; // EDID数据
} loongarch_vesa_shared_info;

// 设备信息结构
typedef struct
{
    int32 handle;                   // 设备句柄
    pci_info pcii;                  // PCI信息
    uint8 *regs;                    // 寄存器虚拟地址
    area_id shared_area;            // 共享区域ID
    loongarch_vesa_shared_info *si; // 共享信息指针
} device_info;

// 设备钩子结构
extern device_hooks gDeviceHooks;

// 设备函数声明
status_t device_init(device_info *di);
void device_uninit(device_info *di);
status_t device_open(const char *name, uint32 flags, void **cookie);
status_t device_close(void *cookie);
status_t device_free(void *cookie);
status_t device_ioctl(void *cookie, uint32 op, void *buffer, size_t length);
status_t device_read(void *cookie, off_t pos, void *buffer, size_t *length);
status_t device_write(void *cookie, off_t pos, const void *buffer, size_t *length);

#endif /* _LOONGARCH_VESA_PRIVATE_H */